#ifndef __LOCK_H__
#define __LOCK_H__

#include <stdint.h>
#include "mb.h"

typedef volatile uint64_t um_lock_t;

#ifdef __cplusplus
extern "C"
{
#endif

    // 原子写操作，将value原子地写入target指针所指的内存位置
    inline static void atomic_write_uint32(uint32_t volatile *target, uint32_t value) {
        // 使用原子交换操作（比较并交换）实现原子写入
        __atomic_store_n(target, value, __ATOMIC_SEQ_CST);
    }

    // 原子读操作，从source指针所指的内存位置中原子地读取数据
    inline static unsigned int atomic_read_uint32(uint32_t volatile *source) {
        // 使用原子加载操作实现原子读取
        return __atomic_load_n(source, __ATOMIC_SEQ_CST);
    }

    inline static void atomic_inc(uint32_t volatile *target){
        __atomic_add_fetch(target, (uint32_t)1, __ATOMIC_SEQ_CST);
    }

    inline static void atomic_dec(uint32_t volatile *target){
        __atomic_sub_fetch(target, (uint32_t)1, __ATOMIC_SEQ_CST);
    }

    inline static void spin_lock(uint64_t volatile *val)
    {
        uint64_t expected = 0;

        // 自旋等待
        while (__sync_val_compare_and_swap(val, expected, 1) != expected)
        {
            // 空循环
        }
        smp_mb();
    }

    inline static void spin_unlock(uint64_t volatile *val)
    {
        smp_mb();
        *val = 0;
    }

#ifdef __cplusplus
}
#endif

#ifdef __cplusplus

class SpinLock
{
private:
    bool m_locked;
    um_lock_t *m_val;

public:
    SpinLock(um_lock_t *val) : m_locked(false), m_val(val)
    {
        // spin_lock(m_val);
        lock();
    }

    void lock()
    {
        if (!m_locked)
        {
            spin_lock(m_val);
            m_locked = true;
        }
    }
    void unlock()
    {
        if (m_locked)
        {
            m_locked = false;
            spin_unlock(m_val);
        }
    }

    ~SpinLock()
    {
        // spin_unlock(m_val);
        unlock();
    }
};

#endif

#endif // __LOCK_H__